package controllers

import (
	"strconv"
	"fmt"
	"layim/models"
	"encoding/json"
	"gopkg.in/kataras/iris.v6/adaptors/websocket"
	"layim/helper"
)

//注册WsId到用户在线状态
func (h *ChatController) SocketRegisterWsIdToUser(userid int64) {
	fromuser := &models.User{Id: userid}
	if h.Orm.First(fromuser).Error != nil {
		h.SocketErrorMessage(userid)
		return
	}
	fromuser.Wsid = h.WsCon.ID()
	fromuser.Status = 1
	//更新用户信息
	if h.Orm.Save(fromuser).Error != nil {
		h.SocketErrorMessage(userid)
		return
	}
	rooms := h.getUserRoomsById(userid)
	if len(rooms) > 0 {
		for _, room := range rooms {
			h.WsCon.Join("chatroom-" + strconv.Itoa(int(room.Id)))
		}
	}
	//发送连接服务器成功信息
	h.WsCon.To(h.WsCon.ID()).EmitMessage(SendWsJsonStr(&websocketJSON{
		Message: "连接Socket服务器成功",
		From:    userid,
		To:      userid,
		Type:    WSEventType.LOGIN,
	}))
}

//信息处理
func (h *ChatController) SocketMessage(fromid int64, toid int64, content string) {
	fromuser := &models.User{}
	touser := &models.User{}
	if h.Orm.First(fromuser, &models.User{Id: fromid}).Error != nil {
		h.SocketErrorMessage(fromid)
		return
	}
	if h.Orm.First(touser, &models.User{Id: toid}).Error != nil {
		h.SocketErrorMessage(fromid)
		return
	}

	//记录聊天记录, 推送消息给对方
	chatlog := &models.Chatlog{UserId: fromid, FriendId: toid, Message: content, Time: helper.GetTimeStamp()}
	if h.Orm.Create(chatlog).Error != nil {
		h.SocketErrorMessage(fromid)
		return
	}
	if touser.Wsid == "" {
		return
	}
	h.WsCon.To(touser.Wsid).EmitMessage(SendWsJsonStr(&websocketJSON{
		From: fromid,
		To:   toid,
		Message: map[string]interface{}{
			"username":  fromuser.Username,
			"type":      "friend",
			"id":        fromuser.Id,
			"avatar":    fromuser.Avatar,
			"content":   content,
			"mine":      false,
			"timestamp": helper.GetTimeStamp() * 1000,
		},
		Type: WSEventType.MESSAGE,
	}))

}

//改变状态
func (h *ChatController) SocketChangeStatus(from, to, status int64) {
	sendData := SendWsJsonStr(&websocketJSON{From: from, To: to, Message: status, Type: WSEventType.CHANGESTATUS})
	if err := h.WsCon.To(websocket.All).EmitMessage(sendData); err != nil {
		fmt.Println(err.Error())
	}
}

func (h *ChatController) SocketAddFriend(from, to int64) {
	//通知对方面板添加人员
	user := &models.User{}
	if h.Orm.First(user, &models.User{Id: to}).RecordNotFound() {
		return
	}
	//this.JSON(iris.StatusOK, responseJSON{Errcode:0, Message:"添加好友成功", Data:map[string]interface{}{
	//	"type":     "friend",
	//	"avatar":   friend.Avatar,
	//	"username": friend.Username,
	//	"groupid":  friend,
	//	"id":       friend.Id,
	//	"sign":     friend.Sign,
	//}})

}

func (h *ChatController) SocketChatRoom(fromid, toid int64, content string) {
	fromuser := &models.User{}
	if h.Orm.First(fromuser, &models.User{Id: fromid}).Error != nil {
		h.SocketErrorMessage(fromid)
		return
	}
	//踩坑,原来是wsid太长,导致无法比较正确的连接ID
	h.WsCon.To("chatroom-" + strconv.Itoa(int(toid))).EmitMessage(SendWsJsonStr(&websocketJSON{
		From: fromid,
		To:   toid,
		Message: map[string]interface{}{
			"username":  fromuser.Username,
			"type":      "group",
			"id":        toid,
			"fromid":    fromid,
			"avatar":    fromuser.Avatar,
			"content":   content,
			"mine":      false,
			"timestamp": helper.GetTimeStamp() * 1000,
		},
		Type: WSEventType.CHATROOM,
	}))
}

//OnMessage websocket总入口处理路由
func (h *ChatController) SocketOnMessage(data []byte) {
	//给对方所有人发送
	var from int64
	message, err := h.SocketParseReceiveMessage(data)
	userid, ok := message["from"] //来源人
	apitype, msok := message["type"]
	toid, hasok := message["to"]
	if err != nil || !ok || !msok {
		h.SocketErrorMessage(int64(userid.(float64)))
		return
	}
	from = int64(userid.(float64))
	switch apitype {
	case WSEventType.LOGIN:
		h.SocketRegisterWsIdToUser(from)
	case WSEventType.MESSAGE:
		content, cok := message["content"]
		if !hasok || !cok {
			h.SocketErrorMessage(from)
			return
		}
		if toid != nil {
			h.SocketMessage(from, int64(toid.(float64)), content.(string))
		}
	case WSEventType.CHANGESTATUS: //{"from":1,"to":0,"status":"hide","type":"change"}
		var status int64
		if message["status"] == "online" {
			status = 1
		} else {
			status = 0
		}
		if toid != nil {
			h.SocketChangeStatus(from, int64(toid.(float64)), status)
		}
	case WSEventType.ADDFRIEND:
		if toid != nil {
			h.SocketAddFriend(from, int64(toid.(float64)))
		}
	case WSEventType.CHATROOM:
		content, cok := message["content"]
		if !hasok || !cok {
			h.SocketErrorMessage(from)
			return
		}
		if toid != nil {
			h.SocketChatRoom(from, int64(toid.(float64)), content.(string))
		}
	}
}

//解析socket接受的数据
func (h *ChatController) SocketParseReceiveMessage(data []byte) (map[string]interface{}, error) {
	message := new(map[string]interface{})
	err := json.Unmarshal(data, message)
	return *message, err
}

//socket 错误信息返回
func (h *ChatController) SocketErrorMessage(userid int64) {
	h.WsCon.EmitMessage(SendWsJsonStr(&websocketJSON{From: userid, To: userid, Message: "服务异常"}))
}

//客户端与服务器断开连接时触发 ,清除记录的WsId
func (h *ChatController) SocketDisconnect() {
	logoutUser := &models.User{}
	if h.Orm.First(logoutUser, &models.User{Wsid: h.WsCon.ID()}).Error == nil {
		logoutUser.Wsid = ""
		logoutUser.Status = 0
		if h.Orm.Save(logoutUser).RowsAffected != 0 {
			//想所有用户推送离线信息
			h.WsCon.To(websocket.All).EmitMessage(SendWsJsonStr(&websocketJSON{
				From:    logoutUser.Id,
				To:      0,
				Message: WSEventType.LOGOUT,
			}))
		}
	}
}
